{% extends "console/layout.html" %}

{% block title %}Dashboard · {{site_name|default('RustPBX')}}{% endblock %}

{% block content %}
<div class="min-h-[70vh] py-6">
    <div class="mx-auto max-w-7xl px-4">
        <!-- Time range selector -->
        <div class="mb-6 rounded-2xl bg-white p-5 shadow-sm ring-1 ring-black/5">
            <div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-end">
                <div class="flex items-center gap-3">
                    <label for="time-range" class="text-xs font-medium uppercase tracking-wide text-slate-500">Time
                        range</label>
                    <div class="relative w-48">
                        <select id="time-range" name="time-range"
                            class="block w-full appearance-none rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm text-slate-700 focus:border-sky-500 focus:outline-none focus:ring-2 focus:ring-sky-200">
                            <option value="10m" {% if range.key=='10m' %} selected{% endif %}>Last 10 minutes</option>
                            <option value="today" {% if range.key=='today' %} selected{% endif %}>Today</option>
                            <option value="yesterday" {% if range.key=='yesterday' %} selected{% endif %}>Yesterday
                            </option>
                            <option value="week" {% if range.key=='week' %} selected{% endif %}>This week</option>
                            <option value="7days" {% if range.key=='7days' %} selected{% endif %}>Last 7 days</option>
                            <option value="30days" {% if range.key=='30days' %} selected{% endif %}>Last 30 days
                            </option>
                        </select>
                        <span class="pointer-events-none absolute inset-y-0 right-3 flex items-center text-slate-400">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
                                class="h-4 w-4">
                                <path fill-rule="evenodd"
                                    d="M5.23 7.21a.75.75 0 011.06.02L10 10.939l3.71-3.71a.75.75 0 111.06 1.062l-4.24 4.242a.75.75 0 01-1.06 0L5.21 8.29a.75.75 0 01.02-1.08z"
                                    clip-rule="evenodd" />
                            </svg>
                        </span>
                    </div>
                </div>
            </div>
        </div>

        <!-- Metrics with emphasis on last 10 minutes -->
        <section class="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
            <div class="rounded-xl bg-white p-5 ring-1 ring-black/5">
                <div class="text-xs text-slate-500">Calls in <span data-range-label>{{ range.period_label_short |
                        default('last 10 minutes') }}</span></div>
                <div class="mt-2 flex items-end justify-between">
                    <div id="metric-total" class="text-3xl font-semibold">{{ metrics.recent10.total | default(0) }}
                    </div>
                    <div id="metric-trend" class="text-xs text-emerald-600">{{ metrics.recent10.trend | default('+0%')
                        }}</div>
                </div>
                <div class="mt-3 h-2 w-full overflow-hidden rounded bg-slate-100">
                    <div id="metric-util-bar" class="h-full bg-sky-500"
                        style="--v: {{ metrics.recent10.util | default(0) }}; width: calc(var(--v) * 1%);"></div>
                </div>
            </div>
            <div class="rounded-xl bg-white p-5 ring-1 ring-black/5">
                <div class="text-xs text-slate-500">Answered in <span data-range-label>{{ range.period_label_short |
                        default('last 10 minutes') }}</span></div>
                <div class="mt-2 flex items-end justify-between">
                    <div id="metric-answered" class="text-3xl font-semibold">{{ metrics.recent10.answered | default(0)
                        }}</div>
                    <div id="metric-asr" class="text-xs text-emerald-600">{{ metrics.recent10.asr | default('—') }}
                    </div>
                </div>
                <div class="mt-3 h-2 w-full overflow-hidden rounded bg-slate-100">
                    <div id="metric-ans-util-bar" class="h-full bg-emerald-500"
                        style="--v: {{ metrics.recent10.ans_util | default(0) }}; width: calc(var(--v) * 1%);"></div>
                </div>
            </div>
            <div class="rounded-xl bg-white p-5 ring-1 ring-black/5">
                <div class="text-xs text-slate-500">Avg call duration (<span data-range-label>{{
                        range.period_label_short | default('last 10 minutes') }}</span>)</div>
                <div class="mt-2 flex items-end justify-between">
                    <div id="metric-acd" class="text-3xl font-semibold">{{ metrics.recent10.acd | default('0s') }}</div>
                    <div class="text-xs text-slate-500"><span id="metric-today-acd">{{ metrics.today.acd | default('0s')
                            }}</span> today</div>
                </div>
                <div class="mt-3 h-2 w-full overflow-hidden rounded bg-slate-100">
                    <div id="metric-acd-util-bar" class="h-full bg-indigo-500"
                        style="--v: {{ metrics.recent10.acd_util | default(0) }}; width: calc(var(--v) * 1%);"></div>
                </div>
            </div>
            <div class="rounded-xl bg-white p-5 ring-1 ring-black/5">
                <div class="text-xs text-slate-500">Active calls</div>
                <div class="mt-2 flex items-end justify-between">
                    <div id="metric-active" class="text-3xl font-semibold">{{ metrics.active | default(0) }}</div>
                    <div class="text-xs text-slate-500">capacity <span id="metric-capacity">{{ metrics.capacity |
                            default(0) }}</span></div>
                </div>
                <div class="mt-3 h-2 w-full overflow-hidden rounded bg-slate-100">
                    <div id="metric-active-util-bar" class="h-full bg-amber-500"
                        style="--v: {{ metrics.active_util | default(0) }}; width: calc(var(--v) * 1%);"></div>
                </div>
            </div>
        </section>

        <!-- Lower grid: left charts, right summaries -->
        <section class="mt-6 grid gap-6 lg:grid-cols-3">
            <div class="lg:col-span-2 rounded-2xl bg-white p-6 ring-1 ring-black/5">
                <div class="flex items-center justify-between">
                    <h2 id="timeline-title" class="text-sm font-semibold text-slate-600">{{ range.timeline_title |
                        default('Last 10 minutes timeline') }}</h2>
                </div>
                <div class="mt-4">
                    <canvas id="timelineChart" class="h-40 w-full"></canvas>
                </div>
            </div>
            <div class="rounded-2xl bg-white p-6 ring-1 ring-black/5">
                <div class="flex items-center justify-between">
                    <h2 class="text-sm font-semibold text-slate-600">Call direction</h2>
                </div>
                <div class="mt-4">
                    <canvas id="callDirectionChart" class="h-44 w-full"></canvas>
                </div>
            </div>
        </section>

        {% set active_calls_preview = active_calls | default([]) %}
        <section class="mt-6 rounded-2xl bg-white p-6 shadow-sm ring-1 ring-black/5">
            <div class="flex flex-col gap-2 sm:flex-row sm:items-baseline sm:justify-between">
                <div>
                    <h2 class="text-sm font-semibold text-slate-600">Active calls · latest 10</h2>
                    <p class="text-xs text-slate-500">Live preview of up to 10 concurrent calls.</p>
                </div>
                <span id="active-updated" class="text-xs text-slate-400">Updated just now</span>
            </div>
            <div class="mt-4 overflow-x-auto">
                <table class="min-w-full divide-y divide-slate-100 text-sm">
                    <thead class="bg-slate-50">
                        <tr>
                            <th scope="col" class="px-3 py-2 text-left font-medium text-slate-500">Caller</th>
                            <th scope="col" class="px-3 py-2 text-left font-medium text-slate-500">Callee</th>
                            <th scope="col" class="px-3 py-2 text-left font-medium text-slate-500">Status</th>
                            <th scope="col" class="px-3 py-2 text-left font-medium text-slate-500">Started</th>
                            <th scope="col" class="px-3 py-2 text-left font-medium text-slate-500">Duration</th>
                        </tr>
                    </thead>
                    <tbody id="active-calls-body" class="divide-y divide-slate-100">
                        {% for call in active_calls_preview %}
                        <tr class="hover:bg-slate-50">
                            <td class="px-3 py-2 font-medium text-slate-700">{{ call.caller }}</td>
                            <td class="px-3 py-2 text-slate-600">{{ call.callee }}</td>
                            <td class="px-3 py-2">
                                <span
                                    class="inline-flex items-center gap-1 rounded-full bg-slate-100 px-2 py-1 text-xs font-medium text-slate-600">
                                    <span class="h-1.5 w-1.5 rounded-full bg-emerald-500"></span>
                                    {{ call.status }}
                                </span>
                            </td>
                            <td class="px-3 py-2 text-slate-500">{{ call.started_at }}</td>
                            <td class="px-3 py-2 text-slate-500">{{ call.duration }}</td>
                        </tr>
                        {% else %}
                        <tr>
                            <td colspan="5" class="px-3 py-6 text-center text-sm text-slate-400">No active calls at the
                                moment.</td>
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </section>
    </div>
</div>
{% set timeline_labels = metrics.recent10.timeline_labels | default([]) %}
{% set timeline_series = metrics.recent10.timeline | default([2, 5, 7, 4, 9, 6, 3, 5, 8, 4]) %}
{% set call_direction_series = call_direction | default({"Inbound": 28, "Outbound": 17, "Internal": 9}) %}
<div id="dashboard-bootstrap" class="hidden"
    data-payload='{{ {"range": range, "metrics": metrics, "call_direction": call_direction, "active_calls": active_calls_preview} | tojson | safe }}'
    data-endpoint="{{ base_path }}/dashboard/data"></div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.4/dist/chart.umd.min.js"></script>
<script>
    (function () {
        const bootstrapNode = document.getElementById('dashboard-bootstrap');
        let payload = null;
        let endpoint = null;
        if (bootstrapNode) {
            endpoint = bootstrapNode.dataset.endpoint || null;
            try {
                payload = JSON.parse(bootstrapNode.dataset.payload || '{}');
            } catch (err) {
                payload = null;
            }
        }
        const bootstrap = { payload, endpoint };
        const rangeSelect = document.getElementById('time-range');
        const elements = {
            total: document.getElementById('metric-total'),
            trend: document.getElementById('metric-trend'),
            utilBar: document.getElementById('metric-util-bar'),
            answered: document.getElementById('metric-answered'),
            asr: document.getElementById('metric-asr'),
            ansUtilBar: document.getElementById('metric-ans-util-bar'),
            acd: document.getElementById('metric-acd'),
            todayAcd: document.getElementById('metric-today-acd'),
            acdUtilBar: document.getElementById('metric-acd-util-bar'),
            active: document.getElementById('metric-active'),
            capacity: document.getElementById('metric-capacity'),
            activeUtilBar: document.getElementById('metric-active-util-bar'),
            timelineTitle: document.getElementById('timeline-title'),
            activeBody: document.getElementById('active-calls-body'),
            activeUpdated: document.getElementById('active-updated')
        };
        const rangeLabels = document.querySelectorAll('[data-range-label]');

        const ctxTimeline = document.getElementById('timelineChart');
        const ctxDirection = document.getElementById('callDirectionChart');
        let timelineChart = null;
        let directionChart = null;

        function initCharts(initialData) {
            if (!window.Chart) {
                return;
            }
            const { metrics, call_direction } = initialData;
            const timelineLabels = metrics?.recent10?.timeline_labels || [];
            const timelineSeries = metrics?.recent10?.timeline || [];

            if (ctxTimeline) {
                timelineChart = new Chart(ctxTimeline, {
                    type: 'line',
                    data: {
                        labels: timelineLabels,
                        datasets: [{
                            label: 'Calls',
                            data: timelineSeries,
                            fill: true,
                            tension: 0.35,
                            borderColor: '#0284c7',
                            backgroundColor: 'rgba(2, 132, 199, 0.15)',
                            pointRadius: 3,
                            pointBackgroundColor: '#0284c7',
                            pointBorderWidth: 0
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        scales: {
                            y: {
                                beginAtZero: true,
                                ticks: {
                                    color: '#64748b'
                                },
                                grid: {
                                    color: 'rgba(148, 163, 184, 0.2)'
                                }
                            },
                            x: {
                                ticks: {
                                    color: '#64748b'
                                },
                                grid: {
                                    display: false
                                }
                            }
                        },
                        plugins: {
                            legend: {
                                display: false
                            }
                        }
                    }
                });
            }

            if (ctxDirection) {
                const directionLabels = Object.keys(call_direction || {});
                const directionValues = directionLabels.map((key) => call_direction[key]);
                directionChart = new Chart(ctxDirection, {
                    type: 'bar',
                    data: {
                        labels: directionLabels,
                        datasets: [{
                            label: 'Calls',
                            data: directionValues,
                            backgroundColor: ['#0ea5e9', '#22c55e', '#a855f7'],
                            borderRadius: 6,
                            barPercentage: 0.6
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        scales: {
                            y: {
                                beginAtZero: true,
                                ticks: {
                                    precision: 0,
                                    color: '#64748b'
                                },
                                grid: {
                                    color: 'rgba(148, 163, 184, 0.2)'
                                }
                            },
                            x: {
                                ticks: {
                                    color: '#64748b'
                                },
                                grid: {
                                    display: false
                                }
                            }
                        },
                        plugins: {
                            legend: {
                                display: false
                            }
                        }
                    }
                });
            }
        }

        function updateCharts(data) {
            if (!timelineChart || !directionChart) {
                initCharts(data);
                return;
            }
            const timelineLabels = data.metrics?.recent10?.timeline_labels || [];
            const timelineSeries = data.metrics?.recent10?.timeline || [];
            timelineChart.data.labels = timelineLabels;
            timelineChart.data.datasets[0].data = timelineSeries;
            timelineChart.update();

            const directionLabels = Object.keys(data.call_direction || {});
            directionChart.data.labels = directionLabels;
            directionChart.data.datasets[0].data = directionLabels.map((key) => data.call_direction[key]);
            directionChart.update();
        }

        function updateMetrics(data) {
            const metrics = data.metrics?.recent10 || {};
            const today = data.metrics?.today || {};
            const active = data.metrics || {};
            rangeLabels.forEach((node) => {
                node.textContent = data.range?.period_label_short || 'last 10 minutes';
            });
            if (elements.total) {
                elements.total.textContent = metrics.total ?? 0;
            }
            if (elements.trend) {
                elements.trend.textContent = metrics.trend ?? '+0%';
                elements.trend.classList.toggle('text-emerald-600', (metrics.trend || '+').startsWith('+'));
                elements.trend.classList.toggle('text-rose-600', (metrics.trend || '+').startsWith('-'));
            }
            if (elements.utilBar) {
                elements.utilBar.style.setProperty('--v', metrics.util ?? 0);
            }
            if (elements.answered) {
                elements.answered.textContent = metrics.answered ?? 0;
            }
            if (elements.asr) {
                elements.asr.textContent = metrics.asr ?? '—';
            }
            if (elements.ansUtilBar) {
                elements.ansUtilBar.style.setProperty('--v', metrics.ans_util ?? 0);
            }
            if (elements.acd) {
                elements.acd.textContent = metrics.acd ?? '0s';
            }
            if (elements.todayAcd) {
                elements.todayAcd.textContent = today.acd ?? '0s';
            }
            if (elements.acdUtilBar) {
                elements.acdUtilBar.style.setProperty('--v', metrics.acd_util ?? 0);
            }
            if (elements.active) {
                elements.active.textContent = active.active ?? 0;
            }
            if (elements.capacity) {
                elements.capacity.textContent = active.capacity ?? 0;
            }
            if (elements.activeUtilBar) {
                elements.activeUtilBar.style.setProperty('--v', active.active_util ?? 0);
            }
            if (elements.timelineTitle) {
                elements.timelineTitle.textContent = data.range?.timeline_title || 'Timeline';
            }
            if (elements.activeUpdated) {
                const ts = new Date();
                elements.activeUpdated.textContent = `Updated ${ts.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
            }
        }

        function renderActiveCalls(calls) {
            if (!elements.activeBody) {
                return;
            }
            const rows = Array.isArray(calls) ? calls : [];
            if (!rows.length) {
                elements.activeBody.innerHTML = '<tr><td colspan="5" class="px-3 py-6 text-center text-sm text-slate-400">No active calls at the moment.</td></tr>';
                return;
            }
            const fragments = rows.map((call) => {
                return `<tr class="hover:bg-slate-50">
                    <td class="px-3 py-2 font-medium text-slate-700">${call.caller}</td>
                    <td class="px-3 py-2 text-slate-600">${call.callee}</td>
                    <td class="px-3 py-2"><span class="inline-flex items-center gap-1 rounded-full bg-slate-100 px-2 py-1 text-xs font-medium text-slate-600"><span class="h-1.5 w-1.5 rounded-full bg-emerald-500"></span>${call.status}</span></td>
                    <td class="px-3 py-2 text-slate-500">${call.started_at}</td>
                    <td class="px-3 py-2 text-slate-500">${call.duration}</td>
                </tr>`;
            });
            elements.activeBody.innerHTML = fragments.join('');
        }

        function applyPayload(payload) {
            if (!payload) {
                return;
            }
            updateMetrics(payload);
            updateCharts(payload);
            renderActiveCalls(payload.active_calls);
        }

        applyPayload(bootstrap.payload);

        if (rangeSelect && endpoint) {
            rangeSelect.addEventListener('change', async (event) => {
                const key = event.target.value;
                try {
                    const resp = await fetch(`${endpoint}?range=${encodeURIComponent(key)}`, {
                        headers: { 'Accept': 'application/json' }
                    });
                    if (!resp.ok) {
                        throw new Error(`Request failed: ${resp.status}`);
                    }
                    const data = await resp.json();
                    applyPayload(data);
                } catch (err) {
                    console.error('Failed to refresh dashboard data', err);
                }
            });
        }
    })();
</script>
{% endblock %}